home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Skunkware 5
/
Skunkware 5.iso
/
src
/
X11
/
xarchie-2.0.9
/
popups.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-06-18
|
4KB
|
153 lines
/*
* popups.c : Generic blocking popup routines
*
* George Ferguson, ferguson@cs.rochester.edu, 23 Apr 1993.
*/
#include <stdio.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include <X11/Xaw/Dialog.h>
extern Widget toplevel; /* this is the only external */
/*
* Functions defined here:
*/
Widget createPopup(); /* Generic popup routines */
void setPopupLabel();
void popupMainLoop();
void popupDone(); /* Call this when done */
static void centerWidgetAndMouse();
/*
* Data defined here:
*/
static int popupIsDone;
/* - - - - - - - - */
Widget
createPopup(basename,num_buttons,callback)
char *basename;
int num_buttons;
XtCallbackProc callback;
{
Widget shell,dialog;
char name[256];
int i;
sprintf(name,"%sShell",basename);
shell = XtCreatePopupShell(name,transientShellWidgetClass,toplevel,NULL,0);
sprintf(name,"%sDialog",basename);
dialog = XtCreateManagedWidget(name,dialogWidgetClass,shell,NULL,0);
for (i=0; i < num_buttons; i++) {
sprintf(name,"%sButton%d",basename,i);
XawDialogAddButton(dialog,name,callback,(XtPointer)i);
}
XtRealizeWidget(shell);
return(shell);
}
void
setPopupLabel(w,basename,str)
Widget w;
char *basename,*str;
{
char name[256];
Widget dialog;
Arg args[1];
sprintf(name,"%sDialog",basename);
dialog = XtNameToWidget(w,name);
XtSetArg(args[0],XtNlabel,str);
XtSetValues(dialog,args,1);
}
/*
* Popup "shell" with an exclusive grab, then dispatch events until
* popupDone becomes True, then pop "shell" down.
*/
void
popupMainLoop(shell)
Widget shell;
{
/* Go synchronous or the widgets don't resize properly */
XSynchronize(XtDisplay(toplevel),True);
/* Center the popup */
centerWidgetAndMouse(shell,toplevel,shell);
/* Beep */
XBell(XtDisplay(toplevel),0);
/* Pop it up and block until one of the buttons is clicked */
popupIsDone = 0;
XtPopup(shell,XtGrabExclusive);
while (!popupIsDone) {
/*
* Only dispatch XEvents since we don't want input events or
* timers to get in the way
*/
XtAppProcessEvent(XtWidgetToApplicationContext(toplevel),XtIMXEvent);
}
/* Okay, pop it down */
XtPopdown(shell);
#ifndef DEBUG
/* Back to normal */
XSynchronize(XtDisplay(toplevel),False);
#endif
}
void
popupDone()
{
popupIsDone = 1;
}
/* - - - - - - - - */
/*
* Center widget "widget" inside widget "pwidget" and warp mouse to middle
* of "mwidget".
*/
static void
centerWidgetAndMouse(widget,pwidget,mwidget)
Widget widget,pwidget,mwidget;
{
Arg args[2];
Window rwin,child;
int x,y,px,py;
unsigned int w,h,pw,ph,bw,d;
/* Get child size */
XGetGeometry(XtDisplay(widget),XtWindow(widget),
&rwin,&x,&y,&w,&h,&bw,&d);
/* Get parent size, position */
XGetGeometry(XtDisplay(pwidget),XtWindow(pwidget),
&rwin,&px,&py,&pw,&ph,&bw,&d);
/* Need position in root window coords, don't ask me why */
XTranslateCoordinates(XtDisplay(widget),XtWindow(pwidget),rwin,
px,py,&x,&y,&child);
px = x;
py = y;
/* Compute child position */
x = px + pw/2 - w/2;
if (x < 0)
x = 0;
else if (x > WidthOfScreen(XtScreen(widget))-w)
x = WidthOfScreen(XtScreen(widget))-w;
y = py + ph/2 - h/2;
if (y < 0)
y = 0;
else if (y > HeightOfScreen(XtScreen(widget))-h)
y = WidthOfScreen(XtScreen(widget))-h;
/* Set child position */
XtSetArg(args[0],XtNx,x);
XtSetArg(args[1],XtNy,y);
XtSetValues(widget,args,2);
/* Get dest size, position */
XGetGeometry(XtDisplay(mwidget),XtWindow(mwidget),
&rwin,&x,&y,&w,&h,&bw,&d);
/* Move mouse there */
XWarpPointer(XtDisplay(mwidget),None,XtWindow(mwidget),
0,0,0,0,w/2,h/2);
}